package com.flower.filter;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.flower.domain.ApiResult;
import com.flower.domain.entity.LoginUser;
import com.flower.domain.entity.User;
import com.flower.enums.ApiCode;
import com.flower.utils.JwtUtil;
import com.flower.utils.RedisUtils;
import com.flower.utils.ThreadUtils;
import com.flower.utils.WebUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;
@Component
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {


    @Resource
    private RedisUtils redisUtils;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //获取请求头中的token
        String token = null;
        log.info("请求地址是{}", request.getRequestURI());
//        if(StringUtils.isBlank(request.getHeader("authorization"))){
//        }else {
//            token = request.getHeader("authorization").substring(6);
//        }
        token = request.getHeader("authorization");
        log.warn("token的值是{}",token);
        if (Objects.isNull(token)) {
            //说明该接口不需要登录 直接放行
            filterChain.doFilter(request, response);
            return;
        }
        //解析获取userid
        Claims claims = null;
        try {
            claims = JwtUtil.parseJWT(token);
        } catch (Exception e) {
            e.printStackTrace();
            //出现异常 token超时 或者token非法
            //响应告诉前端需要重新登录
            //因为统一异常处理和返回值是针对controller层的 所以我们要在这里自己返回一个东西
            ApiResult result = ApiResult.fail(ApiCode.NOT_PERMISSION);
            WebUtils.renderString(response, JSON.toJSONString(result));
            return;
        }
        //userId要区分前台还是后台的用户
        String userId = claims.getSubject();
        //如果是后台请求的话 走这个
        if(request.getRequestURI().contains("reception")){
            log.warn("我是商城前台的请求");
            User user = (User)redisUtils.get("login_id:"+userId);
            //如果获取不到 说明登陆过期 也需要重新登录
            if (Objects.isNull(user)) {
                ApiResult result = ApiResult.fail(ApiCode.NOT_PERMISSION);
                WebUtils.renderString(response, JSON.toJSONString(result));
                return;
            }
            //将前台用户id存储至线程中去
            ThreadUtils.bind(userId);
        }else { //商城后台的请求
            //从redis中获取用户信息
            LoginUser loginUser = (LoginUser)redisUtils.get("login_id:"+userId);
            //如果获取不到 说明登陆过期 也需要重新登录
            if (Objects.isNull(loginUser)) {
                ApiResult result = ApiResult.fail(ApiCode.NOT_PERMISSION);
                WebUtils.renderString(response, JSON.toJSONString(result));
                return;
            }
            //存入SecurityContextHolder
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, null);
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }
        filterChain.doFilter(request, response);
    }
}
